package com.cci.kangdao.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.cci.kangdao.aop.UserThreadLocal;
import com.cci.kangdao.crmapi.CRMHttpClientUtil;
import com.cci.kangdao.crmapi.CRMResponeEntity;
import com.cci.kangdao.crmapi.CRMServiceApiImpl;
import com.cci.kangdao.dao.*;
import com.cci.kangdao.dao.model.*;
import com.cci.kangdao.dto.BaseResponse;
import com.cci.kangdao.dto.response.DictionariesTree;
import com.cci.kangdao.dto.response.WorkOrderReasonTimeoutRecordTVo;
import com.cci.kangdao.model.DiagnoseConclusionInfo;
import com.cci.kangdao.model.TimeoutDic;
import com.cci.kangdao.service.WorkOrderIndividualCasesService;
import com.cci.kangdao.utilTool.LocalTimeUtil;
import com.cci.kangdao.utilTool.tree.TreeUtils;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import net.sf.json.JSONObject;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @description:
 * @author: joe
 * @company: CTY
 * @since: 2023/9/15 16:41
 * @version: V1.0
 **/
@Service
public class WorkOrderIndividualCasesServiceImpl implements WorkOrderIndividualCasesService {
    @Resource
    private WorkOrderIndividualCasesMapper workOrderIndividualCasesMapper;
    @Resource
    private WorkOrderReasonTimeoutRecordTMapper workOrderReasonTimeoutRecordTMapper;
    @Resource
    private WorkOrderOperatorRelationDao workOrderOperatorRelationDao;
    @Resource
    private WorkOrderTDao workOrderTDao;
    @Autowired
    private CRMServiceApiImpl crmServiceApi;
    @Resource
    private AppVersionTDao appVersionTDao;
    @Resource
    private DiagnoseConclusionTDao diagnoseConclusionTDao;
    @Resource
    private RolesTDao rolesTDao;
    @Resource
    private DictionariesTDao dictionariesTDao;

    private int[] WORKORDER_MODIFIABLE = new int[]{18, 4, 5, 6, 7, 8, 9, 10, 11, 12};
    private int[] WORKORDER_MODIFIABLE_TECHNICIAN = new int[]{8, 10, 11, 12}; //技师
    private int[] WORKORDER_MODIFIABLE_STATIONMASTER = new int[]{6, 7, 8, 9, 10, 11, 12}; //站长

    private final static String SYNC_WORKORDER_TIMEOUTREASON = "SyncWorkOrderTimeOutReason";

    private Logger log = Logger.getLogger(this.getClass().getName());

    /**
     * 获取  服务工单详情 点击超时的详情
     *
     * @param orderId
     * @return
     */
    @Override
    public BaseResponse getIndividualCases(Long orderId, String roleNo, HttpServletRequest request) {
        UserT userT = UserThreadLocal.get();
        Map<String,Object> map = new HashMap<>();
        String eAppVersion = request.getHeader("EAppVersion");
        WorkOrderT workOrderT = workOrderTDao.getWorkOrderTByOrderId(orderId);
        if (null == workOrderT) {
            return BaseResponse.error(-99, "请输入正确orderId");
        }
        try {
            //查询个案详情
            WorkOrderIndividualCases workOrderIndividualCases = workOrderIndividualCasesMapper.selectLastByOrderId(orderId);
            //查询   超时原因-详情-记录
            List<WorkOrderReasonTimeoutRecordTVo> list = workOrderReasonTimeoutRecordTMapper.selectList(orderId);

            //技师在诊断维修结论页面，满足以下条件需填写对应的24H超时原因，72H超时原因，提示
            String dbuResolve = appVersionTDao.getVersionCompatible("dbuResolve");
            String appVersion = StringUtils.isNotBlank(workOrderT.getAppVersion()) ? workOrderT.getAppVersion() : eAppVersion;
            String marketType = workOrderT.getMarketType();
            //市场分类：不等于bus 客车市场，或者不等于Truck卡车市场，或者不等于Construction 工程机械市场
            //故障等级=一般故障
            boolean success = StringUtils.isNotEmpty(marketType) && !marketType.equals("Bus 客车") && !marketType.equals("Truck 卡车") && !marketType.equals("Construction 工程机械");
            //诊断维修结论点击提交按钮的时间-工单创建时间
            DiagnoseConclusionInfo conclusionInfo = diagnoseConclusionTDao.getConclusionByOrderId(orderId);
            //是否必填24小时超时原因
            boolean isFill24 = false;
            //是否必填72小时超时原因
            boolean isFill72 = false;
            if (null != conclusionInfo) {
                Integer hours = (int) LocalTimeUtil.getDurationHours(workOrderT.getCreateTime(), conclusionInfo.getCreateTime());
                Integer problemLevel = conclusionInfo.getProblemLevel();
            /*
			 故障等级=一般故障的时候， 工单的RV时长（诊断维修结论点击提交按钮的时间-工单创建时间）>24小时不允许为空
			 故障等级不等于一般故障的时候，工单的RV时长（诊断维修结论点击提交按钮的时间-工单创建时间）>72小时不允许为空
			 */
                log.info("诊断维修结论超时原因必填判断;appVersion:" + appVersion + ";hours:" + hours + ";success:" + success + ";isFill24:" + isFill24 + ";isFill72:" + isFill72);
                if (workOrderT.getOrderChannel() == 1 && StringUtils.isNotBlank(appVersion) && StringUtils.isNotBlank(dbuResolve)
                        && dbuResolve.compareTo(appVersion) <= 0 && success) {
                    isFill24 = null != problemLevel && problemLevel == 1 && hours >= 24;
                    isFill72 = null != problemLevel && problemLevel != 1 && hours >= 72;
                }
            }
            ObjectMapper objectMapper = new ObjectMapper();
            if (CollectionUtils.isNotEmpty(list)) {
                WorkOrderReasonTimeoutRecordTVo recordTVo = list.get(0);
                String rolesNos = "";
                if(null != recordTVo.getCreator()){
                    List<RolesT> rolesList = rolesTDao.getRoleListByUserID(recordTVo.getCreator());
                    List<String> rolesNoList = rolesList.stream().map(RolesT::getRolesNo).filter(a -> StringUtils.isNotBlank(a)).collect(Collectors.toList());
                    rolesNos = StringUtils.join(rolesNoList, ",");
                }
                if (StringUtils.isNotBlank(recordTVo.getTimeoutDic())) {
                    List<TimeoutDic> timeoutDicList = objectMapper.readValue(recordTVo.getTimeoutDic(), new TypeReference<List<TimeoutDic>>() {
                    });
                    for (TimeoutDic timeoutDic : timeoutDicList) {
                        if(StringUtils.isBlank(timeoutDic.getRoles())){
                            timeoutDic.setRoles(rolesNos);
                        }
                        if(!"R0074".equals(roleNo) && StringUtils.isNotBlank(timeoutDic.getRoles()) && timeoutDic.getRoles().contains("R0074")){
                            timeoutDic.setEditFlag(0);
                        } else {
                            timeoutDic.setEditFlag(1);
                        }
                    }
                    String json = objectMapper.writeValueAsString(timeoutDicList);
                    recordTVo.setTimeoutDic(json);
                }
            }
            map.put("individualCases", workOrderIndividualCases != null ? workOrderIndividualCases.getIndividualCases() : "");
            map.put("reasonTimeoutList", list);

            //获取树状图的字典项
            List<Map<String, Object>> listByDTableName = dictionariesTDao.getDictionariesListByDTableName("IndividualCasesCode");
            //树状图排序
            listByDTableName.sort((e1, e2) -> MapUtils.getInteger(e1, "DInt").compareTo(MapUtils.getInteger(e2, "DInt")));
            DictionariesTree dictionariesTree;
            List<DictionariesTree> treeList = new ArrayList<>();
            for (Map<String, Object> dMap : listByDTableName) {
                dictionariesTree = new DictionariesTree();
                dictionariesTree.setID(MapUtils.getLong(dMap, "ID"));
                dictionariesTree.setDInt(MapUtils.getInteger(dMap, "DInt"));
                dictionariesTree.setDValue(MapUtils.getString(dMap, "DValue"));
                dictionariesTree.setRemark(MapUtils.getString(dMap, "Remark"));
                treeList.add(dictionariesTree);
            }
            treeList = TreeUtils.generateTrees(treeList);
            for(DictionariesTree tree : treeList){
                if (null != tree.getDInt() && tree.getDInt() == 3 && isFill24) {
                    tree.setRequired(1);
                }
                if (null != tree.getDInt() && tree.getDInt() == 5 && isFill72) {
                    tree.setRequired(1);
                }
            }
            map.put("individualCasesCode", JSON.toJSONString(treeList, SerializerFeature.WriteMapNullValue));
            boolean editFlag = true;
            boolean showFlag = true;  //区域工程师进入时是否显示   站长技师都显示

            //  站长
            if ("R0041".equals(roleNo)) {
                if (editFlag) {
                    editFlag = Arrays.stream(WORKORDER_MODIFIABLE_STATIONMASTER).anyMatch(arrStatus -> arrStatus == workOrderT.getOrderStatus());
                }
            } else if ("R0033".equals(roleNo)) {  //技师
                if (editFlag) {
                    editFlag = Arrays.stream(WORKORDER_MODIFIABLE_TECHNICIAN).anyMatch(arrStatus -> arrStatus == workOrderT.getOrderStatus());
                }
            } else {
                //工单直派 的区域工程师可以继续编辑
                showFlag = false;
                editFlag = false;
                Map<String, Object> operatorByOrderIdMap = workOrderOperatorRelationDao.getOperatorByOrderId(orderId);
                if (null != operatorByOrderIdMap) {
                    log.error("getIndividualCases:-----operatorByOrderIdMap：--------" + operatorByOrderIdMap.toString());
                    String Phone = MapUtils.getString(operatorByOrderIdMap, "Phone");
                    log.error("getIndividualCases:-----Phone：--------" + Phone);
                    log.error("getIndividualCases:-----userT.getPhone()：--------" + userT.getPhone());
                    if (StringUtils.isNotBlank(Phone)) {
                        editFlag = Phone.equals(userT.getPhone());
                        showFlag = Phone.equals(userT.getPhone());
                    }
                }
            }
            map.put("showFlag", showFlag);
            map.put("editFlag", editFlag);
            map.put("workOrderEditFlag", Arrays.stream(WORKORDER_MODIFIABLE).anyMatch(arrStatus -> arrStatus == workOrderT.getOrderStatus()));
        } catch (Exception e){
            log.error(e.getMessage(), e);
        }
        return BaseResponse.success(map);
    }

    /**
     * 保存或者更新超时记录
     *
     * @param paramStr
     * @return
     */

    @Override
    public BaseResponse workOrderReasonSaveOrUpdate(String paramStr) {
        WorkOrderReasonTimeoutRecordT workOrderReasonTimeoutRecordT = JSON.parseObject(paramStr, WorkOrderReasonTimeoutRecordT.class);
        if (null == workOrderReasonTimeoutRecordT || null == workOrderReasonTimeoutRecordT.getOrderId()) {
            return BaseResponse.error(-99, "参数不能为空");
        }
        //验证工单的状态 是否 可以提交
        //验证工单是否 ；
        WorkOrderT workOrderT = workOrderTDao.getWorkOrderTByOrderId(workOrderReasonTimeoutRecordT.getOrderId());
        if (null == workOrderT || !Arrays.stream(WORKORDER_MODIFIABLE).anyMatch(arrStatus -> arrStatus == workOrderT.getOrderStatus())) {
            return BaseResponse.error("工单不存在或工单状态不可编辑");
        }
        //验证是否可以添加，
        int num = 0;
        UserT userT = UserThreadLocal.get();
        try {
            Map<String, Object> operatorByOrderIdMap = workOrderOperatorRelationDao.getOperatorByOrderId(workOrderReasonTimeoutRecordT.getOrderId());
            //查询   超时原因-详情-记录
            List<WorkOrderReasonTimeoutRecordTVo> list = workOrderReasonTimeoutRecordTMapper.selectList(workOrderReasonTimeoutRecordT.getOrderId());
            ObjectMapper objectMapper = new ObjectMapper();
            if (StringUtils.isNotBlank(workOrderReasonTimeoutRecordT.getTimeoutDic())) {
                List<RolesT> rolesList = rolesTDao.getRoleListByUserID(userT.getId());
                List<String> rolesNoList = rolesList.stream().map(RolesT::getRolesNo).filter(a -> StringUtils.isNotBlank(a)).collect(Collectors.toList());
                String rolesNos = StringUtils.join(rolesNoList, ",");
                List<TimeoutDic> timeoutDicList = objectMapper.readValue(workOrderReasonTimeoutRecordT.getTimeoutDic(), new TypeReference<List<TimeoutDic>>() {
                });
                List<TimeoutDic> lishiList = new ArrayList<>();
                Long lishiCreator = null;
                if (CollectionUtils.isNotEmpty(list)) {
                    WorkOrderReasonTimeoutRecordTVo recordTVo = list.get(0);
                    lishiCreator = recordTVo.getCreator();
                    if (StringUtils.isNotBlank(recordTVo.getTimeoutDic())) {
                        lishiList = objectMapper.readValue(recordTVo.getTimeoutDic(), new TypeReference<List<TimeoutDic>>() {
                        });
                    }
                }
                for (TimeoutDic timeoutDic : timeoutDicList) {
                    boolean isEqual = false;
                    String roles = "";
                    for (TimeoutDic lishi : lishiList) {
                        if (lishi.getDInt().equals(timeoutDic.getDInt())) {
                            if(StringUtils.isNotBlank(lishi.getRoles())){
                                roles = lishi.getRoles();
                            } else {
                                if(null != lishiCreator){
                                    List<RolesT> lishiRolesList = rolesTDao.getRoleListByUserID(lishiCreator);
                                    List<String> lishiRolesListRolesNoList = lishiRolesList.stream().map(RolesT::getRolesNo).filter(a -> StringUtils.isNotBlank(a)).collect(Collectors.toList());
                                    roles = StringUtils.join(lishiRolesListRolesNoList, ",");
                                }
                            }
                            if(CollectionUtils.isNotEmpty(lishi.getTreeList()) && CollectionUtils.isNotEmpty(timeoutDic.getTreeList())){
                                List<Integer> lishiDicIntList = lishi.getTreeList().stream().map(TimeoutDic::getDInt).filter(a -> null != a).collect(Collectors.toList());
                                List<Integer> timeoutDicIntList = timeoutDic.getTreeList().stream().map(TimeoutDic::getDInt).filter(a -> null != a).collect(Collectors.toList());
                                if(lishiDicIntList.containsAll(timeoutDicIntList) && timeoutDicIntList.containsAll(lishiDicIntList)){
                                    isEqual = true;
                                }
                            }

                        }
                    }
                    if (!isEqual) {
                        timeoutDic.setRoles(rolesNos);
                    } else {
                        timeoutDic.setRoles(roles);
                    }
                    if(StringUtils.isBlank(timeoutDic.getRoles())){
                        timeoutDic.setRoles(rolesNos);
                    }
                    String json = objectMapper.writeValueAsString(timeoutDicList);
                    workOrderReasonTimeoutRecordT.setTimeoutDic(json);
                }
            }
            if (null == workOrderReasonTimeoutRecordT.getId()) {//添加
                int EditFlag = 0;
                if (null != operatorByOrderIdMap) {
                    Long userId = MapUtils.getLong(operatorByOrderIdMap, "UserId");
                    if (null != userId) {
                        EditFlag = userT.getId() == userId ? 1 : 0;
                    }
                }
                workOrderReasonTimeoutRecordT.setEditFlag(EditFlag);
                workOrderReasonTimeoutRecordT.setFlag(0);
                workOrderReasonTimeoutRecordT.setCreator(userT.getId());
                workOrderReasonTimeoutRecordT.setCreateTime(LocalTimeUtil.getRealCurrentTime());
                workOrderReasonTimeoutRecordT.setUpdator(userT.getId());
                workOrderReasonTimeoutRecordT.setUpdateTime(LocalTimeUtil.getRealCurrentTime());
                workOrderReasonTimeoutRecordT.setOrderNo(workOrderT.getOrderNo());
                CRMResponeEntity crmResponeEntity = this.syncWorkOderTimeOut(workOrderReasonTimeoutRecordT);
                workOrderReasonTimeoutRecordT.setSyncFlag(null != crmResponeEntity && crmResponeEntity.getStatus() == 0 ? 1 : 0);
                num = workOrderReasonTimeoutRecordTMapper.insertSelective(workOrderReasonTimeoutRecordT);
            } else {//更新
                WorkOrderReasonTimeoutRecordT workOrderReasonTimeoutRecordTSelect = workOrderReasonTimeoutRecordTMapper.selectByPrimaryKey(workOrderReasonTimeoutRecordT.getId());
                int EditFlag = 0;
                Long userId = MapUtils.getLong(operatorByOrderIdMap, "UserId");
                if (workOrderReasonTimeoutRecordTSelect.getEditFlag() == 1 && userT.getId() != userId) {
                    return BaseResponse.error(-99, "暂无权限");
                } else {
                    if (userId != null) {
                        EditFlag = userT.getId() == userId ? 1 : 0;
                    }
                }
                workOrderReasonTimeoutRecordT.setEditFlag(EditFlag);
                workOrderReasonTimeoutRecordT.setUpdator(userT.getId());
                workOrderReasonTimeoutRecordT.setUpdateTime(LocalTimeUtil.getRealCurrentTime());
                num = workOrderReasonTimeoutRecordTMapper.updateByPrimaryKeySelective(workOrderReasonTimeoutRecordT);
            }
        } catch (Exception e){
            log.error(e.getMessage(), e);
        }
        if (num > 0) {
            return BaseResponse.success();
        } else {
            return BaseResponse.error(-99, "添加或更新失败");
        }
    }

    @Override
    public void syncWorkOrderReason() {
        List<WorkOrderReasonTimeoutRecordT> list = workOrderReasonTimeoutRecordTMapper.selectListSync();
        if (CollectionUtils.isNotEmpty(list)) {
            for (WorkOrderReasonTimeoutRecordT workOrderReasonTimeoutRecordT : list) {
                CRMResponeEntity crmResponeEntity = this.syncWorkOderTimeOut(workOrderReasonTimeoutRecordT);
                if (null != crmResponeEntity && crmResponeEntity.getStatus() == 0) {
                    workOrderReasonTimeoutRecordT.setSyncFlag(1);
                    workOrderReasonTimeoutRecordTMapper.updateByPrimaryKeySelective(workOrderReasonTimeoutRecordT);
                }
            }
        }
    }

    public CRMResponeEntity syncWorkOderTimeOut(WorkOrderReasonTimeoutRecordT workOrderReasonTimeoutRecordT) {
        String timeoutDic = workOrderReasonTimeoutRecordT.getTimeoutDic();
        List<DictionariesTree> treeList = JSON.parseArray(timeoutDic, DictionariesTree.class);
        if (CollectionUtils.isEmpty(treeList)) {
            CRMResponeEntity crmResponeEntity = new CRMResponeEntity();
            crmResponeEntity.setStatus(-99);
            crmResponeEntity.setMessage("传入参数为空");
            return crmResponeEntity;
        }
        Map<String, Object> parameter = new HashMap<>();
        parameter.put("workOrderNo", workOrderReasonTimeoutRecordT.getOrderNo());
        parameter.put("Note", workOrderReasonTimeoutRecordT.getRemark());
        for (DictionariesTree dictionariesTree : treeList) {
            List<DictionariesTree> treeListChile = dictionariesTree.getTreeList();
            String str = CollectionUtils.isNotEmpty(treeListChile) ? treeListChile.stream().map(DictionariesTree::getDValue).collect(Collectors.joining(";")) : "";
            if (dictionariesTree.getDInt() == 1) { //4小时超时
                parameter.put("TimeOutReason6", str);
            }
            if (dictionariesTree.getDInt() == 2) { //12小时超时
                parameter.put("TimeOutReason12", str);
            }
            if (dictionariesTree.getDInt() == 3) { //24小时超时
                parameter.put("TimeOutReason24", str);
            }
            if (dictionariesTree.getDInt() == 4) { //48小时超时
                parameter.put("TimeOutReason48", str);
            }
            if (dictionariesTree.getDInt() == 5) { //72小时超时
                parameter.put("TimeOutReason72", str);
            }
        }
        Map<String, Object> cciCrmTokenAndHost = crmServiceApi.getCCICrmTokenAndHost();
        String channelHost = org.apache.commons.collections.MapUtils.getString(cciCrmTokenAndHost, "hostUrl", "")
                + SYNC_WORKORDER_TIMEOUTREASON;
        Map<String, Object> headerParameter = crmServiceApi.addCCIEncryptionHeader(cciCrmTokenAndHost);
        JSONObject jsonObjectResult = CRMHttpClientUtil.httpPOSTRequest(channelHost, headerParameter, parameter);
        return crmServiceApi.getResponeEntity(jsonObjectResult, "数据获取成功");
    }
}
